#include "settings.h"

void check_error(int condition, const char *error_msg, int should_close_server);   // 统一的错误处理函数
void init_queue(ThreadSafeQueue *queue, int capacity);                             // 初始化任务队列
void init_thread_pool(ThreadPool *pool, int thread_count, ThreadSafeQueue *queue); // 初始化线程池
void start_thread_pool(ThreadPool *pool);                                          // 启动线程池
void init_client_manager(ClientManager *manager, int max_clients);                 // 初始化客户端管理器
void handle_client_connection(int epoll_fd, int server_fd);                        // 处理客户端连接
void handle_client_data(int epoll_fd, int client_fd);                              // 处理客户端数据
void graceful_shutdown(int signal);                                                // 优雅关闭服务器
// 日志函数声明
void log_connection(const char *ip, int port, const char *status);
void log_request(const char *ip, int port, const char *filename);
void log_error(const char *error_msg);

int main(int argc, char const *argv[])
{
    // 初始化守护进程
    daemonize(server_fd);
    // 写入pid文件
    write_pid_file();

    // 设置信号处理
    signal(SIGINT, graceful_shutdown);  // Ctrl+C    终止
    signal(SIGTERM, graceful_shutdown); // kill    终止

    // 初始化服务器socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    check_error(server_fd == -1, "套接字创建失败", 0);

    // 设置地址参数
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PROT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    // // 端口复用
    int opt = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));

    // 绑定
    check_error(bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1, "套接字绑定失败", 1);

    // 监听
    check_error(listen(server_fd, LISTENMAX) == -1, "监听失败", 1);
    printf("服务器在 %d 端口启动...\n", PROT);

    // 初始化任务队列
    init_queue(&task_queue, 1024);

    // 初始化线程池
    init_thread_pool(&thread_pool, PTHREADMAX, &task_queue);
    start_thread_pool(&thread_pool);

    // 初始化客户端管理器
    init_client_manager(&client_manager, MAX_CLIENTS);

    // 创建epoll实例
    epoll_fd = epoll_create1(0);
    check_error(epoll_fd == -1, "epoll文件描述符创建失败", 1);

    // 添加服务器socket到epoll
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = server_fd;
    check_error(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1, "服务器socket添加到epoll失败", 1);

    struct epoll_event events[MAXEVENTS];
    while (server_running)
    {
        int nfds = epoll_wait(epoll_fd, events, MAXEVENTS, -1);
        check_error(nfds == -1 && errno != EINTR, "返回就绪事件失败且不是被信号优雅中断", 1);

        for (int i = 0; i < nfds; i++)
        {
            if (events[i].data.fd == server_fd)
            {
                handle_client_connection(epoll_fd, server_fd);
            }
            else
            {
                handle_client_data(epoll_fd, events[i].data.fd);
            }
        }
    }

    graceful_shutdown(0);
    return EXIT_SUCCESS;
}